<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>虚拟DOM</title>
</head>
<body>
<div id="container">
    {{ msg }}<br>
    <input class="inp-text" type="text" v-model="inpText">
    <div class="text-box">
        <p class="show-text">{{ msg }}</p>
    </div>
</div>

<script>
/*
* 1、通过virtualDom创建虚拟节点，将目标盒子内所有子节点添加到其内部，注意这里只是子节点；
2、子节点通过compile进行编译，
* a:如果节点为元素，其nodeType = 1,
* b:如果节点为文本，其nodeType = 3,
* 具体可以查看详情http://www.w3school.com.cn/js...；
3、如果第二步子节点仍有子节点，通过hasChildNodes()来确认，如果有递归调用compile方法。*/
    var container = document.getElementById('container');
    //这里我们把vue实例中的data提取出来，更加直观
    var data = {
        msg: 'Hello world!',
        inpText: 'Input text'
    };
    var fragment = virtualDom(container, data);
    container.appendChild(fragment);

    //虚拟dom创建方法
    function virtualDom(node, data){
        let frag = document.createDocumentFragment();
        let child;
        // 遍历dom节点
        while(child = node.firstChild){
            compile(child, data);
            frag.appendChild(child);
        }
        return frag;
    }

    //编译规则
    function compile(node, data){
        let reg = /\{\{(.*)\}\}/g;
        if(node.nodeType === 1){ // 标签
            let attr = node.attributes;
            for(let i = 0, len = attr.length; i < len; i++){
                console.log(attr[i].nodeName, attr[i].nodeValue);
                if(attr[i].nodeName === 'v-model'){
                    let name = attr[i].nodeValue;
                    node.value = data[name];
                }
            }
            if(node.hasChildNodes()){
                node.childNodes.forEach((item) => {
                    compile(item, data); // 递归
                });
            }
        }
        if(node.nodeType === 3){ // 文本节点
            if(reg.test(node.nodeValue)){
                let name = RegExp.$1;
                name = name.trim();
                node.nodeValue = data[name];
            }
        }
    }
</script>
</body>
</html>